Conversation
46f7545 to
680ff12
Compare
| # expect { result }.to \ | ||
| # change { obj.foo }.from(1).to(2) |
There was a problem hiding this comment.
expect { ... }
.to ...
is more common?
But it does make the discarded matcher problem more obvious.
expect { result }
.to change { obj.foo }.from(1).to(2)
change { obj.bar }.from(3).to(4)
quite easy to spot.
| change | ||
| receive | ||
| receive_messages | ||
| receive_message_chain |
There was a problem hiding this comment.
Is it correct to say that any block matcher is prone to this?
Can we externalize to our language conf this and make it user-configurable, too to allow adding custom matchers?
| def inside_example?(node) | ||
| node.each_ancestor(:block).any? { |ancestor| example?(ancestor) } | ||
| end |
There was a problem hiding this comment.
Now when it's used in three cops, does it make sense to extract to a module?
|
|
||
| it 'registers an offense for standalone `change` in a one-liner example' do | ||
| expect_offense(<<~RUBY) | ||
| specify { change { obj.bar }.from(1).to(2) } |
There was a problem hiding this comment.
I've seen this a couple of times with value matchers, too:
it { validate_precense_of(:email) }But it should be detected already by https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecnoexpectationexample
| it 'does not register an offense for `change` at end of non-example block' do | ||
| expect_no_offenses(<<~RUBY) | ||
| specify do | ||
| [1, 2, 3].each do |n| | ||
| change { obj.foo }.from(n).to(n + 1) | ||
| end | ||
| end | ||
| RUBY | ||
| end |
There was a problem hiding this comment.
Are there legitimate cases for which we want to ignore this?
| specify do | ||
| if change { obj.foo }.from(1).to(2) | ||
| something | ||
| end |
| specify do | ||
| case change { obj.foo }.from(1).to(2) | ||
| when 1 then something | ||
| end | ||
| end |
There was a problem hiding this comment.
I can't imagine a real spec using this
| result = case condition | ||
| when :update then something | ||
| else change { obj.baz }.from(5).to(6) | ||
| end |
There was a problem hiding this comment.
This seems like a probable scenario e.g.
change_temp = case season
when :summer then change { temp }.from(0).to(20)
when :winter then change { temp }.from(20).to(0)
end
expect { advance_clock }.to change_temp| specify do | ||
| case condition | ||
| when change { obj.foo }.from(1).to(2) then something | ||
| end | ||
| end |
There was a problem hiding this comment.
Does it make sense to simplify the cop to only detect cases when a matcher follows the expect?
|
Looks very good and userful overall. My comments here are mostly to suggest narrowing down the scope to detecting just the basic case. I have no objections to merging as is as well if you think weird use cases can cause false offences. |
|
Thank you for your comments! I’ll take them into account and make the necessary updates as soon as possible. |
Legit offence (source): False positive? (source) I believe it's similar to the last year's story from RubyWeekly about a whitespace betweeen the method name and parenthesis. The AST is different. But for RSpec, there's no difference, is there? Those look like false positives (source): |
680ff12 to
5d7a24f
Compare
5d7a24f to
68bfe98
Compare
|
I’ve addressed all comments, added a few follow-up commits (kept them unsquashed for now), and validated the cop against |
pirj
left a comment
There was a problem hiding this comment.
I've run the cop against real-world-rspec (I've updated its submodules with the latest), and the cop detected zero offences. Is that right?
The gitlabhq/spec/services/event_create_service_spec.rb still has the offence.
| specify do | ||
| def expect_action | ||
| expect { action!(performer: performer, context: context) } | ||
| end | ||
|
|
There was a problem hiding this comment.
| specify do | |
| def expect_action | |
| expect { action!(performer: performer, context: context) } | |
| end | |
| def expect_action | |
| expect { action!(performer: performer, context: context) } | |
| end | |
| specify do |
As you mentioned above, detecting that offense is not the responsibility of this cop. Therefore, I only take into account code that already contains $ RUBOCOP_TARGET_RUBY_VERSION=3.4 rubocop ../real-world-rspec/gitlabhq/spec/services/event_create_service_spec.rb -c /dev/null --plugin rubocop-rspec --only RSpec/NoExpectationExample
Offenses:
/home/ydakuka/Work/real-world-rspec/gitlabhq/spec/services/event_create_service_spec.rb:183:7: C: RSpec/NoExpectationExample: No expectation found in this example.
it 'creates new event' do ...
^^^^^^^^^^^^^^^^^^^^^^^^^
1 file inspected, 1 offense detectedI also checked the cop against the examples from the issue description, and it works for me. |
Fixes rubocop/rubocop#14772
Before submitting the PR make sure the following are checked:
master(if not - rebase it).CHANGELOG.mdif the new code introduces user-observable changes.bundle exec rake) passes (be sure to run this locally, since it may produce updated documentation that you will need to commit).If you have created a new cop:
config/default.yml.Enabled: pendinginconfig/default.yml.Enabled: truein.rubocop.yml.VersionAdded: "<<next>>"indefault/config.yml.If you have modified an existing cop's configuration options:
VersionChanged: "<<next>>"inconfig/default.yml.